package com.example.loginstructuredemo.http;


import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;

import com.example.loginstructuredemo.DemoApplication;
import com.example.loginstructuredemo.utils.SPUtils;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Locale;

import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;

/**
 * Created by Alex on 2016/10/19.
 */

public class HttpInterceptor{

	private static final int TIMEOUT_CONNECT = 400; //5秒

	private static final int TIMEOUT_DISCONNECT = 60 * 60 * 24 * 7; //7天

	private static final String TAG = "HttpInterceptor";

	public static final Interceptor REWRITE_RESPONSE_INTERCEPTOR = new Interceptor() {
		@Override
		public okhttp3.Response intercept(Chain chain) throws IOException {

			Request request = chain.request();
			request.newBuilder().addHeader("epdToken", "")
					.addHeader("epdDevice", "android")
					.addHeader("epdVersion", "2.5.2").build();
			long t1 = System.nanoTime();

			//请求日志
			String url = requestLog(request);

			okhttp3.Response originalResponse = chain.proceed(chain.request());
			//打印返回日志
			responseLog(url, t1, originalResponse);

			//获取retrofit @headers里面的参数，参数可以自己定义，在本例我自己定义的是cache，跟@headers里面对应就可以了
			String cache = chain.request().header("cache");
			String cacheControl = originalResponse.header("Cache-Control");

			//如果cacheControl为空，就让他TIMEOUT_CONNECT秒的缓存，本例是5秒，方便观察。注意这里的cacheControl是服务器返回的
			if (cacheControl == null) {
				//如果cache没值，缓存时间为TIMEOUT_CONNECT，有的话就为cache的值
				if (cache == null) {
					cache = TIMEOUT_CONNECT + "";
				}
				originalResponse = originalResponse.newBuilder()
						.header("Cache-Control", "public, max-age=" + cache)
						.build();
				return originalResponse;
			} else {
				return originalResponse;
			}
		}
	};

	public static final Interceptor REWRITE_RESPONSE_INTERCEPTOR_OFFLINE = new Interceptor() {
		@Override
		public okhttp3.Response intercept(Chain chain) throws IOException {
			Request request = chain.request();
			//离线的时候为7天的缓存。
			if (!isNetworkReachable(DemoApplication.getContext())) {
				request = request.newBuilder()
						.header("Cache-Control", "public, only-if-cached, max-stale="+TIMEOUT_DISCONNECT)
						.build();
			}
			return chain.proceed(request);
		}
	};

	/**
	 * 打印请求日志
	 * @param request
	 * @return
	 * @throws IOException
	 */
	private static String requestLog(Request request) throws IOException {
		//request url
		String url = request.url().toString();
		//request method
		String method = request.method();


		Log.d(TAG,String.format(Locale.getDefault(),"Sending %s request [url = %s]",method,url));

		//the request body
		RequestBody requestBody = request.body();
		if(requestBody!= null) {
			StringBuilder sb = new StringBuilder("Request Body [");
			Buffer buffer = new Buffer();
			requestBody.writeTo(buffer);
			Charset charset = Charset.forName("UTF-8");
			MediaType contentType = requestBody.contentType();
			if (contentType != null) {
				charset = contentType.charset(charset);
			}
//			if(isPlaintext(buffer)){
			sb.append(buffer.readString(charset));
			sb.append(" (Content-Type = ").append(contentType.toString()).append(",")
					.append(requestBody.contentLength()).append("-byte body)");
//			}else {
			sb.append(" (Content-Type = ").append(contentType.toString())
					.append(",binary ").append(requestBody.contentLength()).append("-byte body omitted)");
//			}
			sb.append("]");
			Log.d(TAG, String.format(Locale.getDefault(), "%s %s", method, sb.toString()));
		}
		return url;
	}

	/**
	 * 打印返回日志
	 * @param url
	 * @param t1
	 * @param originalResponse
	 * @throws IOException
	 */
	private static void responseLog(String url, long t1, Response originalResponse) throws IOException {
		//本地保存token
		String token = originalResponse.headers().get("epdToken");
		SPUtils.setToken(token, DemoApplication.getContext());
		long t2 = System.nanoTime();
		//the response time
		Log.d(TAG,String.format(Locale.getDefault(),"Received response for [url = %s] in %.1fms",url, (t2-t1)/1e6d));

		//the response state
		Log.d(TAG,String.format(Locale.CHINA,"Received response is %s ,message[%s],code[%d]",originalResponse.isSuccessful()?"success":"fail",originalResponse.message(),originalResponse.code()));

		//the response data
		ResponseBody body = originalResponse.body();

		BufferedSource source = body.source();
		source.request(Long.MAX_VALUE); // Buffer the entire body.
		Buffer buffer = source.buffer();
		Charset charset = Charset.defaultCharset();
		MediaType contentType = body.contentType();
		if (contentType != null) {
			charset = contentType.charset(charset);
		}
		String bodyString = buffer.clone().readString(charset);
		Log.d(TAG,String.format("Received response json string [%s]",bodyString));
	}

	public static Boolean isNetworkReachable(Context context) {
		ConnectivityManager cm = (ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo current = cm.getActiveNetworkInfo();
		if (current == null) {
			return false;
		}
		return (current.isAvailable());
	}

}
